实现反汇编器是可选的，但实现并不需要太多的努力，并且生成反汇编表可能会捕获其他生成器未检查的编码错误。反汇编程序位于m88kdisassemer.cpp文件中，位于Disassembler子目录中:

\begin{enumerate}
\item
通过定义调试类型和DecodeStatus类型开始实现，两个都是生成代码所必需的:

\begin{cpp}
using namespace llvm;
#define DEBUG_TYPE "m88k-disassembler"
using DecodeStatus = MCDisassembler::DecodeStatus;
\end{cpp}

\item
M88kDisassmbler类位于匿名命名空间中，只需要实现getInstruction()方法:

\begin{cpp}
namespace {
class M88kDisassembler : public MCDisassembler {
public:
    M88kDisassembler(const MCSubtargetInfo &STI,
                     MCContext &Ctx)
        : MCDisassembler(STI, Ctx) {}
    ~M88kDisassembler() override = default;

    DecodeStatus
    getInstruction(MCInst &instr, uint64_t &Size,
                    ArrayRef<uint8_t> Bytes,
                    uint64_t Address,
                    raw_ostream &CStream) const override;
};
} // end anonymous namespace
\end{cpp}

\item
还需要提供一个工厂方法，在目标注册中心中注册:

\begin{cpp}
static MCDisassembler *
createM88kDisassembler(const Target &T,
                        const MCSubtargetInfo &STI,
                        MCContext &Ctx) {
    return new M88kDisassembler(STI, Ctx);
}

extern "C" LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeM88kDisassembler() {
    TargetRegistry::RegisterMCDisassembler(
        getTheM88kTarget(), createM88kDisassembler);
}
\end{cpp}

\item
decodeGPRRegisterClass()函数将寄存器号转换为TableGen生成的寄存器枚举成员。这是M88kInstPrinter::getMachineOpValue()方法的逆操作。注意，M88kRegisterOperand类的DecoderMethod字段中指定了这个函数的名称:

\begin{cpp}
static const uint16_t GPRDecoderTable[] = {
    M88k::R0, M88k::R1, M88k::R2, M88k::R3,
    // …
};

static DecodeStatus
decodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
                        uint64_t Address,
                        const void *Decoder) {
    if (RegNo > 31)
        return MCDisassembler::Fail;

    unsigned Register = GPRDecoderTable[RegNo];
    Inst.addOperand(MCOperand::createReg(Register));
    return MCDisassembler::Success;
}
\end{cpp}

\item
然后，包括生成的反汇编表:

\begin{cpp}
#include "M88kGenDisassemblerTables.inc"
\end{cpp}

\item
最后，解码指令，需要获取bytes数组中接下来的四个字节，从中创建指令编码，并调用decodeInstruction()生成的函数:

\begin{cpp}
DecodeStatus M88kDisassembler::getInstruction(
        MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes,
        uint64_t Address, raw_ostream &CS) const {
    if (Bytes.size() < 4) {
        Size = 0;
        return MCDisassembler::Fail;
    }
    Size = 4;

    uint32_t Inst = 0;
    for (uint32_t I = 0; I < Size; ++I)
        Inst = (Inst << 8) | Bytes[I];

    if (decodeInstruction(DecoderTableM88k32, MI, Inst,
                          Address, this, STI) !=
        MCDisassembler::Success) {
        return MCDisassembler::Fail;
    }
    return MCDisassembler::Success;
}
\end{cpp}

\end{enumerate}

这就是反汇编程序需要做的全部工作。编译LLVM后，可以使用llvm-mc工具再次测试功能:

\begin{shell}
$ echo "0xf4,0x22,0x40,0x03" | \
    bin/llvm-mc --triple m88k-openbsd –disassemble
          .text
          and %r1, %r2, %r3
\end{shell}

此外，现在可以使用llvm-objdump工具来反汇编ELF文件。然而，为了使它真正有用，需要将所有指令添加到目标描述中。


























































